/// Basic usage examples for the Price-RS Extension Generator
///
/// This file demonstrates how to use the extension generator programmatically
/// and showcases the different types of extensions that can be generated.
use extension_generator::{
    cli::{ExtensionType, LayerType},
    config::Config,
    generator::{GenerationContext, Generator},
};
use std::path::PathBuf;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    println!("🚀 Price-RS Extension Generator Examples");
    println!();

    // Example 1: Generate a standard extension
    println!("📋 Example 1: Standard Extension");
    generate_standard_extension().await?;
    println!();

    // Example 2: Generate an API-focused extension
    println!("🌐 Example 2: API Extension");
    generate_api_extension().await?;
    println!();

    // Example 3: Generate a lightweight extension
    println!("📦 Example 3: Lightweight Extension");
    generate_lightweight_extension().await?;
    println!();

    // Example 4: Generate a custom extension
    println!("🔧 Example 4: Custom Extension");
    generate_custom_extension().await?;
    println!();

    // Example 5: Configuration usage
    println!("⚙️ Example 5: Configuration Usage");
    demonstrate_configuration()?;
    println!();

    println!("✅ All examples completed successfully!");
    Ok(())
}

/// Example 1: Generate a standard extension with all four layers
async fn generate_standard_extension() -> anyhow::Result<()> {
    let context = GenerationContext::new(
        "example-standard".to_string(),
        Some("Example standard extension with all four layers".to_string()),
        ExtensionType::Standard,
        None, // Use default layers for standard type
        Some("Example Developer".to_string()),
        Some(PathBuf::from("./examples/output/example-standard")),
    );

    println!("  📄 Generating standard extension...");
    println!("     Name: {}", context.name);
    println!("     Type: {:?}", context.extension_type);
    println!("     Layers: {} layers", context.enabled_layers.len());

    for layer in &context.enabled_layers {
        println!("       - {:?}: {}", layer, layer.description());
    }

    let generator = Generator::new();
    generator.generate(&context).await?;

    println!("  ✅ Standard extension generated successfully!");
    Ok(())
}

/// Example 2: Generate an API-focused extension
async fn generate_api_extension() -> anyhow::Result<()> {
    let context = GenerationContext::new(
        "example-api".to_string(),
        Some("Example API service extension".to_string()),
        ExtensionType::Api,
        None, // Use default layers for API type
        Some("API Team".to_string()),
        Some(PathBuf::from("./examples/output/example-api")),
    );

    println!("  🌐 Generating API extension...");
    println!("     Name: {}", context.name);
    println!("     Type: {:?}", context.extension_type);
    println!("     Features: Full HTTP API support");

    let generator = Generator::new();
    generator.generate(&context).await?;

    println!("  ✅ API extension generated successfully!");
    Ok(())
}

/// Example 3: Generate a lightweight extension
async fn generate_lightweight_extension() -> anyhow::Result<()> {
    let context = GenerationContext::new(
        "example-lightweight".to_string(),
        Some("Example lightweight extension for data processing".to_string()),
        ExtensionType::Lightweight,
        None, // Use default layers for lightweight type
        Some("Data Team".to_string()),
        Some(PathBuf::from("./examples/output/example-lightweight")),
    );

    println!("  📦 Generating lightweight extension...");
    println!("     Name: {}", context.name);
    println!("     Type: {:?}", context.extension_type);
    println!("     Focus: Data structures and business logic only");

    let generator = Generator::new();
    generator.generate(&context).await?;

    println!("  ✅ Lightweight extension generated successfully!");
    Ok(())
}

/// Example 4: Generate a custom extension with specific layers
async fn generate_custom_extension() -> anyhow::Result<()> {
    let custom_layers = vec![
        LayerType::Nodes,
        LayerType::Plugins,
        LayerType::Commands,
        // Note: Excluding Router layer for this example
    ];

    let context = GenerationContext::new(
        "example-custom".to_string(),
        Some("Example custom extension with specific layers".to_string()),
        ExtensionType::Custom,
        Some(custom_layers),
        Some("Custom Team".to_string()),
        Some(PathBuf::from("./examples/output/example-custom")),
    );

    println!("  🔧 Generating custom extension...");
    println!("     Name: {}", context.name);
    println!("     Type: {:?}", context.extension_type);
    println!("     Custom layers:");

    for layer in &context.enabled_layers {
        println!("       - {:?}: {}", layer, layer.description());
    }

    let generator = Generator::new();
    generator.generate(&context).await?;

    println!("  ✅ Custom extension generated successfully!");
    Ok(())
}

/// Example 5: Demonstrate configuration usage
fn demonstrate_configuration() -> anyhow::Result<()> {
    println!("  ⚙️ Configuration demonstration...");

    // Create a sample configuration
    let mut config = Config::default();
    config.default_author = Some("Example Developer".to_string());
    config.behavior.auto_format = true;
    config.behavior.generate_tests = true;

    println!("     Default author: {:?}", config.default_author);
    println!("     Auto format: {}", config.behavior.auto_format);
    println!("     Generate tests: {}", config.behavior.generate_tests);

    // Set a custom variable
    config.set("company_name", "Example Corp".to_string())?;
    println!("     Custom variable: company_name = {:?}", config.get("company_name"));

    // Validate configuration
    config.validate()?;
    println!("  ✅ Configuration is valid!");

    Ok(())
}

/// Helper function to demonstrate name transformations
#[allow(dead_code)]
fn demonstrate_name_transformations() {
    use extension_generator::generator::NameContext;

    println!("🏷️  Name Transformation Examples:");

    let examples = vec!["djgc", "fbfx-csxm", "my-extension", "simple-calc"];

    for name in examples {
        let name_ctx = NameContext::from_name(name);
        println!("  Input: {}", name);
        println!("    kebab: {}", name_ctx.kebab);
        println!("    snake: {}", name_ctx.snake);
        println!("    pascal: {}", name_ctx.pascal);
        println!("    camel: {}", name_ctx.camel);
        println!();
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_example_generation() {
        // Test that examples can be generated without errors
        let context = GenerationContext::new(
            "test-extension".to_string(),
            Some("Test extension".to_string()),
            ExtensionType::Lightweight,
            None,
            Some("Test Author".to_string()),
            Some(PathBuf::from("./target/test-output/test-extension")),
        );

        let generator = Generator::new();
        assert!(generator.generate(&context).await.is_ok());
    }

    #[test]
    fn test_configuration() {
        let mut config = Config::default();

        // Test setting and getting values
        assert!(config.set("default_author", "Test Author".to_string()).is_ok());
        assert_eq!(config.get("default_author"), Some("Test Author".to_string()));

        // Test validation
        assert!(config.validate().is_ok());
    }
}
